﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace PuyoNeuron
{
    public class ContextMenu : IUIElement
    {
        static Texture2D sMenuTexture;
        static Texture2D sHilightTexture;
        static SpriteFont sLabelFont;
        bool mSizeTainted;
        bool mDispose;
        Vector2 mTopLeft;
        Vector2 mSize;
        List<ContextItem> mItems;

        public Vector2 TopLeft
        {
            get { return mTopLeft; }
            set { mTopLeft = value; }
        }

        public Vector2 Size
        {
            get { return mSize; }
            set { mSize = value; }
        }

        public List<ContextItem> Items
        {
            get { return mItems; }
        }

        public bool Dispose
        {
            get { return mDispose; }
            set { mDispose = value; }
        }

        static public Texture2D MenuTexture
        {
            get { return sMenuTexture; }
            set { sMenuTexture = value; }
        }

        static public Texture2D HilightTexture
        {
            get { return sHilightTexture; }
            set { sHilightTexture = value; }
        }

        static public SpriteFont LabelFont
        {
            get { return sLabelFont; }
            set { sLabelFont = value; }
        }

        public ContextMenu(Vector2 pTopLeft)
        {
            mTopLeft = pTopLeft;
            mSize = new Vector2(100, 100);
            mItems = new List<ContextItem>();
            mSizeTainted = true;
        }

        public void OnEnter()
        {
        }

        public void OnExit()
        {
        }

        public void OnClick(Vector2 pLocation)
        {

        }

        public void OnRelease(Vector2 pLocation)
        {
            if (pLocation.X > 4 &&
                pLocation.X < mSize.X - 4 &&
                pLocation.Y > 6 &&
                pLocation.Y < mItems.Count() * 20 + 6)
            {
                int lIndex = (int)((pLocation.Y - 6) / 20);
                if (mItems[lIndex].Action != null)
                {
                    mItems[lIndex].Action(mTopLeft);
                    mDispose = true;
                }
            }
        }

        public void OnMouseUp(Vector2 pLocation)
        {

        }

        public void Draw(SpriteBatch pSpriteBatch)
        {
            if (mSizeTainted)
            {
                mSize.Y = 10 + 20 * mItems.Count();
                mSize.X = 80;
                foreach (ContextItem lItem in mItems)
                {
                    if (LabelFont.MeasureString(lItem.Name).X + 20 > mSize.X)
                        mSize.X = LabelFont.MeasureString(lItem.Name).X + 20;
                }
                mSizeTainted = false;
            }

            #region draw box

            // top left
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(0, 0)),
                              new Rectangle(0, 0, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // top edge
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(12, 0)),
                              new Rectangle(12, 0, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(Size.X / 12f - 2, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // top right
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(Size.X - 12, 0)),
                              new Rectangle(24, 0, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // left edge
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(0, 12)),
                              new Rectangle(0, 12, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, Size.Y / 12f - 2) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // middle
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(12, 12)),
                              new Rectangle(12, 12, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(Size.X / 12f - 2, Size.Y / 12f - 2) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // right edge
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(Size.X - 12, 12)),
                              new Rectangle(24, 12, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, Size.Y / 12f - 2) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // bottom left
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(0, Size.Y - 12)),
                              new Rectangle(0, 24, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // bottom edge
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(12, Size.Y - 12)),
                              new Rectangle(12, 24, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(Size.X / 12f - 2, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            // bottom left
            pSpriteBatch.Draw(sMenuTexture,
                              Camera.Instance.ToScreen(TopLeft + new Vector2(Size.X - 12, Size.Y - 12)),
                              new Rectangle(24, 24, 12, 12),
                              Color.White,
                              0,
                              Vector2.Zero,
                              new Vector2(1, 1) * Camera.Instance.Zoom,
                              SpriteEffects.None,
                              0f);

            #endregion

            #region draw hilight
            
            Vector2 lMouseState = Camera.Instance.ToWorld(new Vector2(Mouse.GetState().X, Mouse.GetState().Y));
                        
            if (lMouseState.X > mTopLeft.X + 4 &&
                lMouseState.X < mTopLeft.X + mSize.X - 4 &&
                lMouseState.Y > mTopLeft.Y + 6 &&
                lMouseState.Y < mTopLeft.Y + 6 + mItems.Count() * 20)
            {
                int lY = (int)((lMouseState.Y - mTopLeft.Y - 6) / 20) * 20 + 6;

                // left
                pSpriteBatch.Draw(sHilightTexture,
                                  Camera.Instance.ToScreen(TopLeft + new Vector2(4, lY)),
                                  new Rectangle(0, 0, 8, 20),
                                  Color.White,
                                  0,
                                  Vector2.Zero,
                                  new Vector2(1, 1) * Camera.Instance.Zoom,
                                  SpriteEffects.None,
                                  0f);

                // middle
                pSpriteBatch.Draw(sHilightTexture,
                                  Camera.Instance.ToScreen(TopLeft + new Vector2(12, lY)),
                                  new Rectangle(8, 0, 8, 20),
                                  Color.White,
                                  0,
                                  Vector2.Zero,
                                  new Vector2(Size.X / 8f - 3f, 1) * Camera.Instance.Zoom,
                                  SpriteEffects.None,
                                  0f);

                // right
                pSpriteBatch.Draw(sHilightTexture,
                                  Camera.Instance.ToScreen(TopLeft + new Vector2(Size.X - 12, lY)),
                                  new Rectangle(16, 0, 8, 20),
                                  Color.White,
                                  0,
                                  Vector2.Zero,
                                  new Vector2(1, 1) * Camera.Instance.Zoom,
                                  SpriteEffects.None,
                                  0f);
            }

            #endregion

            for (int i = 0; i < mItems.Count(); i++)
            {
                pSpriteBatch.DrawString(sLabelFont, mItems[i].Name,
                                        Camera.Instance.ToScreen(mTopLeft + new Vector2(10, 6 + i * 20)),
                                        mItems[i].Action == null ? Color.Gray : Color.White,
                                        0f,
                                        Vector2.Zero,
                                        Camera.Instance.Zoom,
                                        SpriteEffects.None,
                                        0f);
            }
        }

        public class ContextItem
        {
            public string Name { get; set; }
            public Game1.ClickAction Action { get; set; }

            public ContextItem(string pName, Game1.ClickAction pAction)
            {
                Name = pName;
                Action = pAction;
            }
        }
    }
}